package decision_tree.question;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

import decision_tree.pos.POSManager;

public class NgramQuestionGenerator implements QuestionGenerator {

	@Override
	public List<Question> generate(Properties properties) {
		int max_ngram = Integer.parseInt(properties.getProperty("max_ngram"));
		
		List<String> posList = getPosList();
		
		return generate(posList, max_ngram);
	}
	
	protected List<String> getPosList() {
		return new ArrayList<String>(POSManager.getInstance().getAbstractSet());
	}
	
	protected List<Question> generate(List<String> posList, int max_ngram) {
		List<Question> questionList = new LinkedList<Question>();
		for(int i = 1; i <= max_ngram; i++) {
			questionList.addAll(generateNgram(posList, i));
		}
		return questionList;
	}
	
	protected List<Question> generateNgram(List<String> posList, int n) {
		List<List<String>> permutation = getPermutation(posList, n);
		return getQuestions(permutation);
	}

	protected List<List<String>> getPermutation(List<String> posList, int n) {
		int counter = getCount(posList.size(), n);
		List<Integer> baseList = getBaseList(posList.size(), n);
		
		List<List<String>> list = new ArrayList<List<String>>(counter);
		
		for(int i = 0; i < counter; i ++) {
			List<String> item = new ArrayList<String>(n);
			
			int remain = i;
			for(int j = 0; j < n; j++) {
				int base = baseList.get(j);
				int index = remain / base;
				item.add(posList.get(index));
				remain = remain % base;
				
			}
			list.add(item);
		}
		
		return list;
	}
	
	protected int getCount(int size, int n) {
		int r = 1;
		for(int i = 0; i < n; i++) {
			r *= size;
		}
		return r;
	}
	
	protected List<Integer> getBaseList(int size, int n) {
		List<Integer> list = new ArrayList<Integer>(n);
		int r = 1;
		for(int i = 0; i < n; i++) {
			list.add(r);
			r *= size;
		}
		
		// reverse
		List<Integer> reversed = new ArrayList<Integer>(n);
		for(int i = list.size() - 1; i >= 0; i --) {
			reversed.add(list.get(i));
		}
		
		return reversed;
	}
	
	protected List<Question> getQuestions(List<List<String>> permutation) {
		List<Question> list = new ArrayList<Question>(permutation.size());
		for(List<String> pattern : permutation) {
			Question q = getNewQuestion();
			q.initialize(pattern);
			list.add(q);
		}
		return list;
	}
	
	protected Question getNewQuestion() {
		return new NgramQuestion();
	}
}
